#ifndef CNEURALNET_H
#define CNEURALNET_H

#include <vector>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <limits.h>

using namespace std;

/********************************NEURONA***********************************/
struct Neurona
{
  //nro de inputs,
  uint32_t cant_inputs;
  //vector de weight
  double* weight;

  Neurona(uint32_t cant_inputs);
};

/************************************************************************/

/****************************CAPA_NEURONAL*******************************/
struct CapaNeuronal
{
  //nro de neuronas,
  uint32_t cant_neuronas;
  //nro outputs
//  uint32_t cant_outputs;
  //vector de neuronas
  Neurona* neuronas;

  CapaNeuronal(uint32_t cant_neuronas,
      uint32_t cant_inputs/*,uint32_t cant_outputs*/);
};

/***********************************************************************/

/*****************************RED_NEURONAL******************************/
class RedNeuronal
{

private:

  uint32_t cant_inputs;
  uint32_t cant_outputs;

  vector<CapaNeuronal> capas;

  vector<vector<double> > GenerarOutput(vector<double> in);
public:

  static float TOLERANCIA;
  static const unsigned int MAX_ITERACIONES = UINT_MAX;
  RedNeuronal(uint32_t cantInputs, uint32_t cantOutputs);

  /*
   * Agrega una capa
   */
  void
  AgregarCapaNeuronal(uint32_t cant_neuronas/*, uint32_t cant_outputs*/);

  /*
   * Obtiene la salida para la entrada pasada como arg
   */
  vector<double>
  Pensar(vector<double> &inputs);

  inline double
  Sigmoid(double activation, double response);

  double
  DerivativeSigmoid(double activation, double response);

  void
  Entrenar(vector<vector<double> > input, vector<vector<double> > target);

};

/***********************************************************************/

#endif
